Linked list cycle II

Time: O(N); Space: O(1); medium

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note:

  • Do not modify the linked list.

Example 1:

Input: head = {ListNode} 3->2->0->-4->None

Output: 2 (tail connects to node index 1)

Explanation:

  • There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = {ListNode} 1->2->None

Output: 1 (tail connects to node index 0)

Explanation:

  • There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = {ListNode} 1->None

Output: None

Explanation:

  • There is no cycle in the linked list.

Follow-up:

  • Can you solve it without using extra space?

[11]:
class ListNode(object):
    def __init__(self, x):
        self.val = x
        self.next = None

    def __str__(self):
        if self:
            return "{}".format(self.val)
        else:
            return None
[12]:
class Solution1(object):
    """
    Time: O(N)
    Space: O(1)
    """
    def detectCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if not head or not head.next:
            return None

        fast, slow = head, head

        while fast and fast.next:
            fast, slow = fast.next.next, slow.next
            if fast is slow:
                fast = head
                while fast is not slow:
                    fast, slow = fast.next, slow.next
                return fast

        return None
[14]:
s = Solution1()

head = ListNode(3)
head.next = ListNode(2)
head.next.next = ListNode(0)
head.next.next.next = ListNode(-4)
head.next.next.next.next = head.next
assert s.detectCycle(head).val == 2

head = ListNode(1)
head.next = ListNode(2)
head.next.next = head
assert s.detectCycle(head).val == 1

head = ListNode(1)
assert s.detectCycle(head) == None